package com.wmh.baseservice.operationaid.service.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wmh.baseservice.admin.entity.AdInfo;
import com.wmh.baseservice.admin.service.AdInfoService;
import com.wmh.baseservice.common.ex.ServiceException;
import com.wmh.baseservice.common.mybatisplus.structure.LambdaQueryWrapperX;
import com.wmh.baseservice.common.utils.CollectionUtil;
import com.wmh.baseservice.operationaid.convert.product.ProductMonitorRecordConvert;
import com.wmh.baseservice.operationaid.entity.ProductMonitorRecord;
import com.wmh.baseservice.operationaid.mapper.ProductMonitorRecordMapper;
import com.wmh.baseservice.operationaid.pojo.vo.product.monitorrecored.ProductMonitorRecordCommitReqVO;
import com.wmh.baseservice.operationaid.service.ProductMonitorRecordService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author 谢骏
 * @description 针对表【operation_aid_product_monitor_record(运营助手-商品监控记录)】的数据库操作Service实现
 * @createDate 2023-09-25 15:52:26
 */
@Service
public class ProductMonitorRecordServiceImpl extends ServiceImpl<ProductMonitorRecordMapper, ProductMonitorRecord>
        implements ProductMonitorRecordService {

    @Resource
    private MailAccount systemMailAccount;

    @Resource
    private AdInfoService adInfoService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void robotCommit(ProductMonitorRecordCommitReqVO reqVO) {
        List<ProductMonitorRecord> entityList = ProductMonitorRecordConvert.INSTANCE.convertList(reqVO);
        // 获取监控目标已经存在的记录
        List<ProductMonitorRecord> oldRecords = baseMapper.selectList(new LambdaQueryWrapperX<ProductMonitorRecord>()
                .eq(ProductMonitorRecord::getPushUnitId, reqVO.getPushUnitId())
                .eq(ProductMonitorRecord::getProductId, reqVO.getProductId()));
        // 获取在库最新的记录
        Map<Long, ProductMonitorRecord> lastRecordMap = getLastRecord(oldRecords);
        List<ProductMonitorRecord> saveList = new ArrayList<>();
        // key 旧 / value 新
        Map<ProductMonitorRecord, ProductMonitorRecord> exitsUpdate = new HashMap<>();
        for (ProductMonitorRecord item : entityList) {
            ProductMonitorRecord old = lastRecordMap.get(item.getSkuId());
            // 不存在即新插入的商品
            if (old == null) {
                saveList.add(item);
            } else {
                // sku 正文不同 / sku 价格不同
                if (!item.getSkuContent().equals(old.getSkuContent()) || item.getPrice().compareTo(old.getPrice()) != 0) {
                    exitsUpdate.put(old, item);
                    saveList.add(item);
                    continue;
                }
                // 不是同一天
                if (!LocalDateTimeUtil.isSameDay(LocalDateTimeUtil.now(), old.getCreateTime())) {
                    saveList.add(item);
                }
            }
        }
        saveBatch(saveList);
        sendMail(exitsUpdate, reqVO.getAdId());
    }

    private void sendMail(Map<ProductMonitorRecord, ProductMonitorRecord> exitsUpdateMap, Long adId) {
        if (MapUtil.isEmpty(exitsUpdateMap)) {
            return;
        }
        AdInfo adInfo = adInfoService.getById(adId);
        if (adInfo == null) {
            throw new ServiceException(StrUtil.format("管理员已经不存在 : {}", adId));
        }
        if (StrUtil.isBlank(adInfo.getEmail())) {
            throw new ServiceException(StrUtil.format("该管理员没有邮箱 : {} ", adId));
        }
        String html = buildMailContent(exitsUpdateMap);

        MailUtil.send(systemMailAccount, adInfo.getEmail(), "赫巴兹智能办公系统-商品sku变动提醒", html, true);
    }

    private void appendTableRow(StringBuilder content, ProductMonitorRecord record) {
        content.append("<tr>");
        content.append("<td>").append(record.getProductId()).append("</td>");
        content.append("<td>").append(record.getSkuId()).append("</td>");
        content.append("<td>").append(record.getSkuContent()).append("</td>");
        content.append("<td>").append(record.getPrice()).append("</td>");
        content.append("<td>")
                .append(StrUtil.format("<a href=\"https://item.taobao.com/item.htm?id={}&skuId={}\">打开详情页</a>", record.getProductId(), record.getSkuId()))
                .append("</td>");
        content.append("</tr>");
    }

    private String buildMailContent(Map<ProductMonitorRecord, ProductMonitorRecord> exitsUpdateMap) {
        StringBuilder content = new StringBuilder("<html><body>");

        for (Map.Entry<ProductMonitorRecord, ProductMonitorRecord> entry : exitsUpdateMap.entrySet()) {
            ProductMonitorRecord oldRecord = entry.getKey();
            ProductMonitorRecord newRecord = entry.getValue();

            // 创建一个表格，并将字段值插入到表格中
            content.append("<table>");
            content.append("<tr><th>商品编号</th><th>sku编号</th><th>sku正文</th><th>价格</th><th>操作</th></tr>");

            // 添加旧记录的表格行
            appendTableRow(content, oldRecord);

            // 添加新记录的表格行
            appendTableRow(content, newRecord);

            content.append("</table>");

            // 添加换行
            content.append("<br>");
        }

        content.append("</body></html>");
        return content.toString();
    }


    /**
     * 获取最新的记录
     *
     * @param records 已经在数据库的数据
     * @return key: skuId / value: 数据
     */
    public Map<Long, ProductMonitorRecord> getLastRecord(List<ProductMonitorRecord> records) {
        Map<Long, List<ProductMonitorRecord>> recordMap = CollectionUtil.convertMultiMap(records, ProductMonitorRecord::getSkuId);
        Map<Long, ProductMonitorRecord> latestRecordMap = new HashMap<>(recordMap.size());
        recordMap.keySet().forEach(key -> {
            // 获取每个 sku 最近的获取的数据
            Optional<ProductMonitorRecord> max = recordMap.get(key).stream().max(Comparator.comparing(ProductMonitorRecord::getCreateTime));
            max.ifPresent(item -> latestRecordMap.put(key, item));
        });
        return latestRecordMap;
    }
}




